/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package amfservices;

import config.ConfigDB;
import java.lang.reflect.*;
import java.util.*;
import libCore.Config;
import models.FakeData;
import models.MixPenguinModel;
import models.U_BoxEggModel;
import models.U_CoteModel;
import models.U_FriendModel;
import models.U_IbshopModel;
import models.U_PenguinModel;
import models.UserModel;
import share.ShareConstants;
import utilities.time.UtilTime;


/**
 *
 * @author linhta
 */
public class Service {
    //==========================================
    // AMF service name

    public Map<String, Object> loadGame(HashMap<String, Object> params)
    {
        if( !FakeData.getInstance().IsRun )
        {
            FakeData.getInstance().setUser();
            FakeData.getInstance().IsRun = true;
        }
        
        return reflectCall("loadGame", params);
    }

    public Map<String, Object> getFriendList(HashMap<String, Object> params) 
    {
        
        return reflectCall("getFriendList", params);
    }

    public Map<String, Object> getDataFriend(HashMap<String, Object> params) 
    {
        return reflectCall("getDataFriend", params);
    }

    //=============== Hieu ==========================
    public Map<String, Object> helpFriendFood( HashMap<String, Object> params ) 
    {
        return reflectCall("helpFriendFood", params);
    }
    
    public Map<String, Object> getCote( HashMap<String, Object> params ) 
    {
        return reflectCall("getCote", params);
    }
    
    public Map<String, Object> updateUserLevelUp( HashMap<String, Object> params ) 
    {
        return reflectCall("updateUserLevelUp", params);
    }
    
    public Map<String, Object> buyPenguin( HashMap<String, Object> params ) 
    {
        return reflectCall("buyPenguin", params);
    }
    
    public Map<String, Object> dropFish( HashMap<String, Object> params ) 
    {
        return reflectCall("dropFish", params);
    }
    
    public Map<String, Object> buyFish( HashMap<String, Object> params ) 
    {
        return reflectCall("buyFish", params);
    }
    
    public Map<String, Object> sellPenguin( HashMap<String, Object> params ) 
    {
        return reflectCall("sellPenguin", params);
    }
    
    public Map<String, Object> penguinEat( HashMap<String, Object> params ) 
    {
        return reflectCall("penguinEat", params);
    }
    
    public Map<String, Object> penguinsEat( HashMap<String, Object> params ) 
    {
        return reflectCall("penguinsEat", params);
    }
    
    public Map<String, Object> penguinLevelUp( HashMap<String, Object> params ) 
    {
        return reflectCall("penguinLevelUp", params);
    }
    
    public Map<String, Object> upgradeBoxEgg( HashMap<String, Object> params ) 
    {
        return reflectCall("upgradeBoxEgg", params);
    }
    
    public Map<String, Object> upgradeCote( HashMap<String, Object> params ) 
    {
        return reflectCall("upgradeCote", params);
    }
    
    public Map<String, Object> sellEggs( HashMap<String, Object> params ) 
    {
        return reflectCall("sellEggs", params);
    }
    
    public Map<String, Object> stealEgg( HashMap<String, Object> params ) 
    {
        return reflectCall("stealEgg", params);
    }
    
    public Map<String, Object> giveEgg( HashMap<String, Object> params ) 
    {
        return reflectCall("giveEgg", params);
    }
    
    public Map<String, Object> sellEggNotId( HashMap<String, Object> params ) 
    {
        return reflectCall("sellEggNotId", params);
    }
    
    public Map<String, Object> mixPenguin( HashMap<String, Object> params ) 
    {
        return reflectCall("mixPenguin", params);
    }
    //=============== Hieu ==========================
    
    //================= Coin =========================
    public Map<String, Object> increaseExpPeng( HashMap<String, Object> params ) 
    {
        return reflectCall("increaseExpPeng", params);
    }
    
    public Map<String, Object> increaseLevelPeng( HashMap<String, Object> params ) 
    {
        return reflectCall("increaseLevelPeng", params);
    }
    
    public Map<String, Object> increaseLevelCote( HashMap<String, Object> params ) 
    {
        return reflectCall("increaseLevelCote", params);
    }
    
    public Map<String, Object> increaseLevelBoxEgg( HashMap<String, Object> params ) 
    {
        return reflectCall("increaseLevelBoxEgg", params);
    }
    
    public Map<String, Object> increaseUserGold( HashMap<String, Object> params ) 
    {
        return reflectCall("increaseUserGold", params);
    }
    
    public Map<String, Object> increaseUserCoin( HashMap<String, Object> params ) 
    {
        return reflectCall("increaseUserCoin", params);
    }
    //==========================================
    
    private Map<String, Object> reflectCall(String method, HashMap<String, Object> params) 
    {
        HashMap<String, Object> content = new HashMap<String, Object>();

        content.put("warning", "test");
        //params.get("userId")
        float parVerConf;
        parVerConf = Float.valueOf(params.get("verConfig").toString());

        float verConf;
        String verConfStr = Config.getParam("config", "version");
        verConf = Float.valueOf(verConfStr);
        Map<String, Object> config = new HashMap<String, Object>();

        if (verConf != parVerConf) {
            config.put("version", verConf);
            config.put("config", ConfigDB.getClientConfig());

            content.put("config", config);
        }

        long time   =    UtilTime.getTimeNow();
        content.put( "timeServer", time );
        
        try {

            //
            Method mthd = getClass().getMethod("rf_" + method, HashMap.class);
            try {
                @SuppressWarnings("unchecked")
                HashMap<String, Object> result = (HashMap<String, Object>) mthd.invoke(this, params);
                for (Map.Entry<String, Object> entry : result.entrySet()) {
                    content.put(entry.getKey(), entry.getValue());
                }
            } catch (InvocationTargetException ex) {
                // Pass exception to global throwable catch statements
                //throw ex.getCause();
                content.put("error", 1);
            }
        } catch (NoSuchMethodException ex) {
            HashMap<String, Object> error = new HashMap<String, Object>();
            error.put("message", ex.getMessage());
            content.put("error", error);
        } catch (SecurityException ex) {
            HashMap<String, Object> error = new HashMap<String, Object>();
            error.put("message", ex.getMessage());
            content.put("error", error);
        } catch (IllegalAccessException ex) {
            HashMap<String, Object> error = new HashMap<String, Object>();
            error.put("message", ex.getMessage());
            content.put("error", error);
        } catch (IllegalArgumentException ex) {
            HashMap<String, Object> error = new HashMap<String, Object>();
            error.put("message", ex.getMessage());
            content.put("error", error);
        }

        return content;
    }

    //==========================================
    public Map<String, Object> rf_loadGame(HashMap<String, Object> params) throws Exception 
    {
        HashMap<String, Object> amfLoad = new HashMap<String, Object>();

        String uid =   params.get( ShareConstants.UID ).toString();
        UserModel uModel = new UserModel( uid );
        Map<String, Object> data = uModel.getDataUser();
        
        amfLoad.put( ShareConstants.USER, data);
        return amfLoad;
    }

    //=========== Hieu =====
    
    public Map<String, Object> rf_getDataFriend(HashMap<String, Object> params) throws Exception 
    {
        Map<String, Object> amfResult = new HashMap<String, Object>();

        String uid =   params.get( ShareConstants.UID ).toString();
        String fid =   params.get( ShareConstants.FID ).toString();
        U_FriendModel frModel       =   new U_FriendModel( uid );
        Map<String, Object> data    =   frModel.getDataDetailFriend( fid );
        
        amfResult.put(share.ShareMacros.FRIENDS, data );
        
        return amfResult;
    }

    public Map<String, Object> rf_getFriendList(HashMap<String, Object> params) throws Exception 
    {
        HashMap<String, Object> amfFriends = new HashMap<String, Object>();

        String uid         =   params.get( ShareConstants.UID ).toString();
        
        U_FriendModel frModel       =   new U_FriendModel( uid );
        Map<String, Object> data    =   frModel.getFriendList( uid );

        amfFriends.put( ShareConstants.FRIENDS, data );
        
        return amfFriends;
    }

    // Have never tested
    public Map<String, Object> rf_getCote( HashMap<String, Object> params )throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid             =   params.get( ShareConstants.UID ).toString();
        Map<String, Object> data    =   null;
        if( UserModel.isExist(uid) ) {
            String coteId   =   params.get( ShareConstants.COTE_ID ).toString();
            
            U_CoteModel coteModel   =   new U_CoteModel( uid );
            data    =   coteModel.getUserCote( coteId ).toAMF();
        }
        
        amfResult.put( ShareConstants.COTE, data );
        
        System.out.println( "---------> Result get cote: " + ( data != null ? "Success" : "Failed" ) );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_updateUserLevelUp( HashMap<String, Object> params )throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid          =   params.get( ShareConstants.UID ).toString();
        UserModel uModel    =   new UserModel( uid );
        boolean result      =   uModel.increaseLevelByOne();
        amfResult.put( ShareConstants.CAN_LEVEL_UP, result );
        
        System.out.println( "---------> Result user level up: " + (result ? "Success" : "Failed") );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_buyPenguin( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid          =   params.get( ShareConstants.UID ).toString();
        String buyResult;
        
        U_IbshopModel shopModel =   new U_IbshopModel( uid );
        if( params.get( ShareConstants.PAYMENT_TYPE ).equals( ShareConstants.PAYMENT_TYPE_GOLD ) ) { // by gold
            buyResult = shopModel.buyPenguinByGold( (String)params.get( ShareConstants.ITEM_TYPE ), (String)params.get( ShareConstants.COTE_ID ) );
        } else { // buy coin
            buyResult = shopModel.buyPenguinByCoin( (String)params.get( ShareConstants.ITEM_TYPE ), (String)params.get( ShareConstants.COTE_ID ) );
        }
        
        amfResult.put( ShareConstants.CAN_BUY, !buyResult.equals( ShareConstants.EMPTYDATA ));
        amfResult.put( ShareConstants.PENG_ID, buyResult );
        
        System.out.println( "---------> Result buy penguin: " + (!buyResult.equals( ShareConstants.EMPTYDATA ) ? "Success" : "Failed") );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_sellPenguin( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        int uid     =   Integer.parseInt( params.get( ShareConstants.UID ).toString() );
        boolean canSell   =   true;
        
        amfResult.put( ShareConstants.CAN_SELL, canSell );
        
        System.out.println( "---------> Result sell penguin: " + ( canSell ? "Success" : "Failed") );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_dropFish( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        String coteId   =   params.get( ShareConstants.COTE_ID ).toString();
        int nFish       =   Integer.parseInt( params.get( ShareConstants.FISH ).toString() );
        
        U_CoteModel coteModel   =   new U_CoteModel( uid );
        Boolean result  =   coteModel.dropFish( coteId, nFish );
        
        amfResult.put( ShareConstants.CAN_DROP, result );
        System.out.println( "---------> Result pengs " + "has eat" );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_buyFish( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        String itemType =   params.get( ShareConstants.ITEM_TYPE ).toString();
        
        U_IbshopModel shopModel =   new U_IbshopModel( uid );
        amfResult.putAll( shopModel.buyFish( itemType ) );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_penguinEat( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        String coteId   =   params.get( ShareConstants.COTE_ID ).toString();
        String pengId   =   params.get( ShareConstants.PENG_ID ).toString();
        
        System.out.println( "----------------- Call penguin " + pengId + " eat from client" );
        
        UserModel u     =   new UserModel( uid );
        if( u.isValidCote( coteId ) ) 
        {
            U_CoteModel coteModel   =   new U_CoteModel( uid );
            amfResult   =   coteModel.feedPenguin( coteId, pengId );
        }
        
        return amfResult;
    }
    
    public Map<String, Object> rf_penguinsEat( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        String coteId   =   params.get( ShareConstants.COTE_ID ).toString();
        
        ArrayList<String> pengs  =   new ArrayList<String>();
        int numberPeng  =   Integer.parseInt( params.get( ShareConstants.NUMBER_PENGUIN ).toString() );
        for( int i = 0; i < numberPeng; ++i )
        {
            String pengId   =   params.get( ShareConstants.PENG_ID + i ).toString();
            pengs.add( pengId );
        }
        amfResult.put( ShareConstants.NUMBER_PENGUIN, numberPeng );
        
        U_CoteModel coteModel   =   new U_CoteModel( uid );
        amfResult.put( ShareConstants.PENG_ID, coteModel.feedPenguins( coteId, pengs ));
        
        System.out.println( "---------> Result pengs " + "has eat" );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_penguinLevelUp ( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        System.out.println( "----- Call penguin level up from client" );
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        String pengId   =   params.get( ShareConstants.PENG_ID ).toString();
        
        U_PenguinModel pengModel    =   new U_PenguinModel( uid );
        Map<String, Object> result  =   pengModel.pegLevelUp( params );
        amfResult.put( pengId, result );
            
        return amfResult;
    }
    
    public Map<String, Object> rf_helpFriendFood( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        String friendId =   params.get( ShareConstants.FID ).toString();
        String coteId   =   params.get( ShareConstants.COTE_ID ).toString();
        int vFood       =   Integer.parseInt( params.get( ShareConstants.FISH ).toString() );
        
        Boolean result  =   U_FriendModel.helpFriendFood(uid, friendId, coteId, vFood);
        
        System.out.println( "----------------- food has help " + ( result ? "Success" : "Failed" ) );
        amfResult.put( ShareConstants.CAN_DROP, result );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_upgradeBoxEgg( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        String coteId   =   params.get( ShareConstants.COTE_ID ).toString();
        
        Boolean result;
        U_BoxEggModel boxModel  =   new U_BoxEggModel( uid );
        if( params.get( ShareConstants.PAYMENT_TYPE ).equals( ShareConstants.PAYMENT_TYPE_GOLD ) ) { 
            // upgrade by gold
            result = boxModel.upgradeBoxEggByGold( coteId );
        } else { 
            // upgrade by coin
            result = boxModel.upgradeBoxEggByCoin( coteId );
        }
        
        amfResult.put( ShareConstants.CAN_UPGRADE, result );
        
        System.out.println( "----------------- box egg has upgrade " + ( result ? "Success" : "Failed" ) );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_upgradeCote( HashMap<String, Object> params ) throws Exception 
    {
         Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        String coteId   =   params.get( ShareConstants.COTE_ID ).toString();
        
        Boolean result;
        U_CoteModel coteModel   =   new U_CoteModel( uid );
        if( params.get( ShareConstants.PAYMENT_TYPE ).equals( ShareConstants.PAYMENT_TYPE_GOLD ) ) { 
            // upgrade by gold
            result = coteModel.upgradeCoteByGold( coteId );
        } else { 
            // upgrade by coin
            result = coteModel.upgradeCoteByCoin( coteId );
        }
        
        amfResult.put( ShareConstants.CAN_UPGRADE, result );
        
        System.out.println( "----------------- cote has upgrade " + ( result ? "Success" : "Failed" ) );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_stealEgg( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        String friendId =   params.get( ShareConstants.FID ).toString();
        String coteId   =   params.get( ShareConstants.COTE_ID ).toString();
        String eggId   =   params.get( ShareConstants.EGG_ID ).toString();
        
        int eggValue    =   U_FriendModel.stealFriendEgg(uid, friendId, coteId, eggId);
        
        Boolean result  =   eggValue != -1;
        System.out.println( "-----> Result: " + ( result ? "Success" : "Failed") );
        
        amfResult.put( ShareConstants.CAN_SELL, result );
        amfResult.put( ShareConstants.EGG_PRICE, eggValue );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_giveEgg( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult;
        
        System.out.println( "----- Call give egg  random from client" );
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        
        U_CoteModel coteModel   =   new U_CoteModel( uid );
        amfResult   =   coteModel.updatePenguin( params );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_sellEggs( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   String.valueOf( params.get( ShareConstants.UID) );
        String coteId   =   String.valueOf( params.get( ShareConstants.COTE_ID ));
        
        int numberEgg  =   Integer.parseInt( params.get( ShareConstants.NUMBER_EGG ).toString() );
        Map<String, Object> removed =   new HashMap<String, Object>();
        String[] eggIds =   new String[numberEgg];
        removed.put( ShareConstants.NUMBER_EGG, numberEgg );
        for( int i = 0; i < numberEgg; ++i )
        {
            String eggId   =   params.get( ShareConstants.EGG_ID + i ).toString();
            eggIds[i]      =   eggId;
            removed.put( ShareConstants.EGG_ID + i, eggId );
        }
        
        System.out.println( "----- Call sell egg from client" );
        
        U_CoteModel coteModel   =   new U_CoteModel( uid );
        amfResult.put( "NEW_EGG", coteModel.sellEggsBox( coteId, eggIds ) );
        amfResult.put( "REMOVED_EGG", removed );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_sellEggNotId( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   String.valueOf( params.get( ShareConstants.UID) );
        String eggType  =   String.valueOf( params.get( ShareConstants.EGG_TYPE ));
        String coteId   =   String.valueOf( params.get( ShareConstants.COTE_ID ));
        String location =   String.valueOf( params.get( ShareConstants.EGG_LOCATION) );
        
        System.out.println( "----- Call sell egg  random from client" );
        
        Boolean result;
        U_CoteModel coteModel   =   new U_CoteModel( uid );
        int gold    =   coteModel.sellEggRandomInSand( coteId, eggType );
        
        result      =   gold != -1;
        System.out.println( "-----> Result: " + ( result ? "Success" : "Failed") );
        
        amfResult.put( ShareConstants.CAN_SELL, result );
        amfResult.put( ShareConstants.EGG_PRICE, gold );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_mixPenguin( HashMap<String, Object> params ) throws Exception 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   String.valueOf( params.get( ShareConstants.UID) );
        MixPenguinModel mixModel        =   new MixPenguinModel( uid );
        Map<String, Object> data        =   mixModel.Mix(params);
        amfResult.putAll( data );
        System.out.println( "-----> Result mix penguin: " + 
                (Boolean.parseBoolean(data.get( ShareConstants.CAN_MIX).toString()) ? "Success" : "Failed") );
        
        return amfResult;
    }
    
    //=========== Hieu =====
    
    //=========== Cheat ====
    public Map<String, Object> rf_increaseExpPeng( HashMap<String, Object> params ) 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        String coteId   =   params.get( ShareConstants.COTE_ID ).toString();
        String pengId   =   params.get( ShareConstants.PENG_ID ).toString();
        int amount      =   Integer.parseInt(params.get( "exp" ).toString());
        
        System.out.println( "----------------- rf_increaseExpPeng " + pengId + " from client" );
        
        UserModel u     =   new UserModel( uid );
        if( u.isValidCote( coteId) )
        {
            U_PenguinModel pengModel    =   new U_PenguinModel( uid );
            amfResult   =   pengModel.increaseExpPeng( pengId, amount );
        }
        
        return amfResult;
    }
    
    public Map<String, Object> rf_increaseLevelPeng( HashMap<String, Object> params ) 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        String coteId   =   params.get( ShareConstants.COTE_ID ).toString();
        String pengId   =   params.get( ShareConstants.PENG_ID ).toString();
        
        System.out.println( "----------------- rf_increaseLevelPeng " + pengId + " from client" );
        
        UserModel u     =   new UserModel( uid );
        if( u.isValidCote( coteId ) )
        {
            U_PenguinModel pengModel    =   new U_PenguinModel( uid );
            amfResult   =   pengModel.increaseLevelPeng( pengId );
        }
        
        return amfResult;
    }
    
//    public Map<String, Object> rf_increaseLevelCote( HashMap<String, Object> params ) {
//    }
//    
//    public Map<String, Object> rf_increaseLevelBoxEgg( HashMap<String, Object> params ) {
//    }
    
    public Map<String, Object> rf_increaseUserGold( HashMap<String, Object> params ) 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        int gold        =   Integer.parseInt(params.get( "gold" ).toString());
        
        UserModel u     =   new UserModel( uid );
        Boolean canIncrease =   u.increaseUserGold( gold );
        
        amfResult.put( "canIncrease", canIncrease );
        amfResult.put( "gold", gold );
        
        return amfResult;
    }
    
    public Map<String, Object> rf_increaseUserCoin( HashMap<String, Object> params ) 
    {
        Map<String, Object> amfResult   =   new HashMap<String, Object>();
        
        String uid      =   params.get( ShareConstants.UID ).toString();
        int coin        =   Integer.parseInt(params.get( "coin" ).toString());
        
        UserModel u     =   new UserModel( uid );
        Boolean canIncrease =   u.increaseUserCoin( coin );
        
        amfResult.put( "canIncrease", canIncrease );
        amfResult.put( "coin", coin );
        
        return amfResult;
    }
    
    
    
    
    
    
    //==========================================

    public static void main(String[] args) {
        System.out.print(Config.getParam("config", "version"));
    }
}